using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Web.UI.HtmlControls;
using ALib;
using ALib.Data.CSVOperation;
using ALib.Data.IO;
using ALib.Misc;
//using ALib.Net;
using TradingPlatform.IB.Operations;

namespace TradingPlatform.IB.Utility
{
    internal class HistoricalDataRequestInfo
    {
        public int _tradingPlatformTimeZoneIndex;
        public int _exchangeTimeZoneIndex;
        public string _exchange;
        public string _secType;
        public string _symbol;
        public string _expiry;
        public string _currency;
        public DateTime _date;

        public HistoricalDataRequestInfo(int tradingPlatformTimeZoneIndex, int exchangeTimeZoneIndex, string exchange, string secType, string symbol, string expiry, string currency, DateTime date)
        {
            _tradingPlatformTimeZoneIndex = tradingPlatformTimeZoneIndex;
            _exchangeTimeZoneIndex = exchangeTimeZoneIndex;
            _exchange = exchange;
            _secType = secType;
            _symbol = symbol;
            _expiry = expiry;
            _currency = currency;
            _date = date;
        }
    }

    class TradingKernel_SaveHistoricalData:TradingKernel
    {
        private InteractiverBrokers _interactiverBrokers;

        private readonly List<string> _signatureList;
        private readonly List<HistoricalDataRequestInfo> _historicalDataRequestInfoList;

        public TradingKernel_SaveHistoricalData()
            : base("InteractiveBrokers_SaveHistoricalData")
        {
            _signatureList = new List<string>();
            _historicalDataRequestInfoList = new List<HistoricalDataRequestInfo>();
            _tradingKernelConfiguration = new Configuration(@"Configuration\TradingKernel_ForHistoricalData.txt");
        }

        public TradingKernel_SaveHistoricalData(bool start)
            : this()
        {
            if (start)
            {
                ConnectTradingApi();
                StartTimerBasedTrading();   
            }
        }

        public override void ConnectTradingApi()
        {
            _interactiverBrokers = new InteractiverBrokers(TradingComm);
            string connectReply = _interactiverBrokers.Connect();
            DisplayStatus(connectReply);
        }

        protected override void InitToStart()
        {
            const string savePath = @"Log\HistoricalData";

            for (DateTime date = new DateTime(2009, 1, 1); date < DateTime.Now.Date; date = date.AddDays(1))
            {
                if (date.DayOfWeek == DayOfWeek.Saturday || date.DayOfWeek == DayOfWeek.Sunday)
                {
                    continue;
                }
                foreach (string tickerName in _tickerInfoDb.TickerNameList)
                {
                    string tradingPlatformTimeZoneIndex = _tickerInfoDb.GetTickerInfoItem(tickerName, TickerInfoItemType.tradingPlatformTimeZoneIndex);
                    string exchangeTimeZoneIndex = _tickerInfoDb.GetTickerInfoItem(tickerName, TickerInfoItemType.exchangeTimeZoneIndex);
                    string exchange = _tickerInfoDb.GetTickerInfoItem(tickerName, TickerInfoItemType.exchange);
                    string secType = _tickerInfoDb.GetTickerInfoItem(tickerName, TickerInfoItemType.secType);
                    string symbol = _tickerInfoDb.GetTickerInfoItem(tickerName, TickerInfoItemType.symbol);
                    string currency = _tickerInfoDb.GetTickerInfoItem(tickerName, TickerInfoItemType.currency);

                    for (int i = 0; i < 6; i++)
                    {
                        string expiry = date.AddMonths(i).ToString("yyyyMM");

                        string signature = string.Join(",", new string[] { tradingPlatformTimeZoneIndex, exchangeTimeZoneIndex, exchange, secType, symbol, expiry, currency, date.ToString(DateTimeFormatType.DateSimple) });
                        if (!_signatureList.Contains(signature))
                        {
                            string dataFileName = string.Format(@"{0}\{1}\{2}.csv", savePath, string.Join("@", new string[] { exchange, secType, symbol, expiry, currency }), date.ToString(DateTimeFormatType.DateSimple));
                            if (!File.Exists(dataFileName))
                            {
                                _signatureList.Add(signature);
                                _historicalDataRequestInfoList.Add(new HistoricalDataRequestInfo(int.Parse(tradingPlatformTimeZoneIndex), int.Parse(exchangeTimeZoneIndex), exchange, secType, symbol, expiry, currency, date));
                            }
                        }
                    }
                }
            }
        }

        protected override void Timer0_Process()
        {
            if (_historicalDataRequestInfoList.Count == 0)
            {
                _timer0.Stop();
            }
            else
            {
                HistoricalDataRequestInfo h = _historicalDataRequestInfoList[0];
                int tradingPlatformTimeZoneIndex = h._tradingPlatformTimeZoneIndex;
                int exchangeTimeZoneIndex = h._exchangeTimeZoneIndex;
                string exchange = h._exchange;
                string secType = h._secType;
                string symbol = h._symbol;
                string expiry = h._expiry;
                string currency = h._currency;
                DateTime date = h._date;

                DateTime endDateTimeOfTradingPlatform = date + new TimeSpan(24+6, 0, 0);
                TimeSpan duration = new TimeSpan(22, 0, 0);
                const string barSize = KeyWordsBarSize.Min_1;
                const string whatToShowType = KeyWordsWhatToShowType.TRADES;
                const bool useRegularTradingHours = true;
                _interactiverBrokers.HistoricalBars.RequestHistoricalBars(tradingPlatformTimeZoneIndex, exchangeTimeZoneIndex, exchange, secType, symbol, expiry, currency, endDateTimeOfTradingPlatform, duration, barSize, whatToShowType, useRegularTradingHours);
            }

            // Display error messages.
            foreach (string errorMessage in _interactiverBrokers.ErrorMessageList)
            {
                DisplayErrorMessage(errorMessage);
            }
            _interactiverBrokers.ErrorMessageList.Clear();
        }

        protected override void Timer1_Process()
        {
            const string savePath = @"Log\HistoricalData";

            if (_interactiverBrokers.HistoricalBars._result.Count > 0)
            {
                foreach (KeyValuePair<string, List<string>> tickerName_Bars in _interactiverBrokers.HistoricalBars._result)
                {
                    string date = _historicalDataRequestInfoList[0]._date.ToString(DateTimeFormatType.DateSimple);
                    string dataFileName = string.Format(@"{0}\{1}\{2}.csv", savePath, tickerName_Bars.Key, date);
                    GoodValue.Assert(!File.Exists(dataFileName));

                    for (int i = tickerName_Bars.Value.Count - 1; i >= 0; i--)
                    {
                        int dataDate = int.Parse(tickerName_Bars.Value[i].Split(new char[] { ',' })[0]);
                        if (dataDate != int.Parse(date))
                        {
                            tickerName_Bars.Value.RemoveAt(i);
                        }
                    }

                    FilesIO.ToOneFile(tickerName_Bars.Value, new FileInfo(dataFileName));
                    DisplayStatus(string.Format(@"Saved to [{0}]", dataFileName));
                }
            }
            _historicalDataRequestInfoList.RemoveAt(0);
            _interactiverBrokers.HistoricalBars._result.Clear();
        }

        protected override void Timer2_Process()
        {
            //throw new System.NotImplementedException();
        }

        protected override void Timer3_Process()
        {
            //throw new System.NotImplementedException();
        }

        protected override void RequestMarketData()
        {
            throw new System.NotImplementedException();
        }

        protected override void SendOrders(List<string> orders)
        {
            throw new System.NotImplementedException();
        }

        public override void Dispose()
        {
            if (_interactiverBrokers != null)
            {
                _interactiverBrokers.Disconnect();
                _interactiverBrokers.Dispose();
            }
        }

        protected override SortedList<string, string> GetStrategyTickerNameList(List<string> tickerNameList)
        {
            throw new System.NotImplementedException();
        }
    }
}
